/*
 * @Description:
 * @Author: LCL
 * @Date: 2021-11-19
 * @LastEditors: LCL
 * @LastEditTime: 2021-12-13
 * @FilePath: /beff/src/components/drag/FrontEndEvent/index.tsx
 */
import React, { useState } from 'react';
import { PauseCircleOutlined, PlayCircleOutlined, PlusOutlined } from '@ant-design/icons';
import type { RadioChangeEvent } from 'antd';
import {
  Button,
  Drawer,
  Form,
  Input,
  Modal,
  Result,
  Tabs,
  Select,
  Radio,
  message,
  Popconfirm,
} from 'antd';
import classNames from 'classnames';
import _ from 'lodash';
import { useModel } from 'umi';
import HBModal from './HBModal';
import ResultModal from './ResultModal';
import styles from './index.less';
import InsertItem from './insertItem';
import DebuggerDrawer from './DebuggerDrawer';

interface ModalFormProps {
  visible: boolean;
  handleClose: () => void;
}
interface IResultObj {
  action: { name: string; value: string }[];
  action_rely: string[];
}

const initEditObj: IFormEventObj = {
  action: [],
  action_rely: [],
  description: '',
  enabled: true,
  id: '',
  name: '',
  request: { body: [], format: 'JSON', header: [], method: 'get', url: '' },
  request_rely: [],
  trigger: '',
};

const FrontEndEvent: React.FC<ModalFormProps> = ({ visible, handleClose }) => {
  const { contentItem, formEventObj, setFormEventObj } = useModel('drag', (modal) => {
    console.log(modal.config);
    return {
      contentItem: modal.config.contentItem || [],
      formEventObj: modal.config.formEventObj,
      setFormEventObj: modal.fn.setFormEventObj,
    };
  });
  // console.log(contentItem);
  const options = contentItem.map((item: { id: string; title: string; field: string }) => {
    return { name: item.field, label: item.title, value: item.id };
  });

  const [modalVisible, setModalVisible] = useState(false);
  const [HBMVisible, setHBMVisible] = useState(false);
  const [resultVisible, setResultVisible] = useState(false);
  const [requestType, setRequestType] = useState<RequestType>('get');
  const [debuggingVisible, setDebuggingVisible] = useState(false);
  const [form] = Form.useForm();
  const [headerBody, setHeaderBody] = useState<any>({ header: [], body: [] });
  const [resultObj, setResultObj] = useState<IResultObj>({ action: [], action_rely: [] });
  const [formEventList, setFormEventList] = useState([...Object.values(formEventObj)]);
  const [editItem, setEditItem] = useState<IFormEventObj>(initEditObj);
  const initialValues = { requestType: 'get', format: 'JSON', triggerName: 'initialValue' };

  const icon = (
    <img
      height="160"
      src="https://g.jdycdn.com/app/pc/v330/resources/images/empty_status/content_empty.png"
    />
  );

  const radioChange = (e: RadioChangeEvent) => {
    setRequestType(e.target.value);
  };

  const onSave = () => {
    form.submit();
    if (!form.getFieldValue('url')) {
      console.log('url未填');
      message.error('url未填');
    }
  };

  const getFieldList = (str: string) => {
    const pannet = /(?<=\$\{)[^}]*(?=\})/g;
    const newStr = str.match(pannet);
    return newStr;
  };

  const onFinish = (values: any) => {
    const id = form.getFieldValue('id') || new Date().getTime();
    let bodyValues = headerBody.body?.map((item: any) => {
      return getFieldList(item.value);
    });
    let requestRely = getFieldList(values.url);
    if (requestRely?.length) {
      bodyValues = _.flatten(bodyValues);
      requestRely = requestRely.concat(bodyValues ? bodyValues : []);
    } else {
      requestRely = _.flatten(bodyValues);
    }
    const obj = {
      action: resultObj.action,
      action_rely: resultObj.action_rely,
      description: values.description,
      enabled: true,
      id,
      name: values.name,
      request: {
        body: headerBody.body,
        format: values.format,
        header: headerBody.header,
        method: values.requestType,
        url: values.url,
      },
      request_rely: _.uniq(requestRely),
      trigger: values.triggerName,
    };
    const formEventObjNew = JSON.parse(JSON.stringify(formEventObj));
    formEventObjNew[id] = obj;
    const arr: any[] = Object.values(formEventObjNew);
    // componentsConfigNew.formEvent = [...arr, obj];
    setFormEventObj(formEventObjNew);
    setModalVisible(false);
    setFormEventList([...arr]);
  };

  const handleDelete = (id: string) => {
    const formEventObjNew: Record<string, IFormEventObj> = JSON.parse(JSON.stringify(formEventObj));
    delete formEventObjNew[id];
    setFormEventObj(formEventObjNew);
    setFormEventList([...Object.values(formEventObjNew)]);
  };

  const handleEdit = (e: React.MouseEvent) => {
    const data = JSON.parse((e.target as any).dataset.formevent);
    form.setFieldsValue({
      id: data.id,
      name: data.name,
      description: data.description,
      triggerName: data.trigger,
      format: data.request.format,
      requestType: data.request.method,
      url: data.request.url,
    });
    setHeaderBody({ header: data.request.header, body: data.request.body });
    setResultObj({ action: data.action, action_rely: data.action_rely });
    setModalVisible(true);
  };

  const footer = [
    <Button
      key="back"
      onClick={() => {
        setModalVisible(false);
      }}
    >
      取消
    </Button>,
    <Button key="submit" type="primary" onClick={onSave}>
      保存
    </Button>,
    // <Button
    //   key="link"
    //   type="primary"
    //   onClick={() => {
    //     onSave();
    //     setDebuggingVisible(true);
    //   }}
    // >
    //   保存并调试
    // </Button>,
  ];

  const normalBtn = classNames(styles.titleBtn, { [styles.normal]: true });
  const deleteBtn = classNames(styles.titleBtn, { [styles.delete]: true });

  return (
    <Form.Provider
      onFormFinish={(name, { values, forms }) => {
        if (name === 'headerForm') {
          const header = values.header || [];
          const body = values.body || [];
          const obj = { header: [...header], body: [...body] };
          console.log(obj);
          setHeaderBody({ ...obj });
          setHBMVisible(false);
        }
        if (name === 'resultForm') {
          setResultVisible(false);
        }
        if (name === 'formEvents') {
          console.log(forms.formEvents.getFieldsValue());
        }
      }}
    >
      <Drawer
        title="前端事件"
        placement="bottom"
        height="95%"
        closable={true}
        onClose={() => {
          handleClose();
        }}
        visible={visible}
        headerStyle={{ textAlign: 'center' }}
        bodyStyle={{ background: '#F4F5F5' }}
        key="bottom"
      >
        {formEventList.length === 0 ? (
          <Result
            icon={icon}
            subTitle="前端事件可以在填写或编辑数据时，让表单字段值的变动触发一系列自动操作。"
            extra={
              <Button
                icon={<PlusOutlined />}
                onClick={() => {
                  setModalVisible(true);
                }}
                type="primary"
              >
                添加前端事件
              </Button>
            }
          />
        ) : (
          // 列表渲染
          <div className={styles.mainBox}>
            <div className={styles.header}>
              <Button
                icon={<PlusOutlined />}
                onClick={() => {
                  setModalVisible(true);
                  setRequestType('get');
                  setHeaderBody({ header: [], body: [] });
                  form.setFieldsValue({
                    id: null,
                  });
                }}
                type="primary"
              >
                添加前端事件
              </Button>
            </div>

            <div className={styles.paneMain}>
              {formEventList.map((item) => {
                return (
                  <div className={styles.listItem} key={item.id}>
                    <div
                      className={classNames(
                        styles.paneWatermark,
                        { [styles.enable]: item.enabled },
                        { [styles.pause]: !item.enabled },
                      )}
                    >
                      <div className={styles.text}>{item.enabled ? '已启用' : '已暂停'}</div>
                    </div>
                    <div className={styles.itemTitleLine}>
                      <div className={styles.title}>{item.name}</div>
                      <div>
                        <Popconfirm
                          title="确定要删除此前端事件?"
                          onConfirm={() => {
                            handleDelete(item.id);
                          }}
                          // onCancel={cancel}
                          className={deleteBtn}
                          okText="确认"
                          cancelText="取消"
                        >
                          <a href="#">删除</a>
                        </Popconfirm>
                      </div>
                      <div
                        className={normalBtn}
                        onClick={handleEdit}
                        data-formevent={JSON.stringify(item)}
                      >
                        编辑
                      </div>
                      <div
                        className={normalBtn}
                        onClick={() => {
                          setDebuggingVisible(true);
                          setEditItem(item);
                          console.log('obj', item);
                        }}
                      >
                        调试
                      </div>
                      <div
                        className={normalBtn}
                        onClick={() => {
                          // setEnable(!enable);
                          item.enabled = !item.enabled;
                          const formEventObjNew = JSON.parse(JSON.stringify(formEventObj));
                          formEventObjNew[item.id] = item;
                          const arr: any[] = Object.values(formEventObjNew);
                          setFormEventObj(formEventObjNew);
                          setFormEventList([...arr]);
                        }}
                      >
                        {item.enabled ? (
                          <PlayCircleOutlined className={styles.icon} />
                        ) : (
                          <PauseCircleOutlined className={styles.icon} />
                        )}
                        {item.enabled ? '启用' : '暂停'}
                      </div>
                    </div>
                    <div className={styles.itemDescriptionLine}>{item.description}</div>
                    <div className={styles.paneLine}>
                      当「<span className="key">{item.trigger}</span>」值发生变动时；
                    </div>
                    <div className={styles.paneLine}>发送GET请求。</div>
                  </div>
                );
              })}
            </div>
          </div>
        )}

        <Modal
          title="前端事件"
          centered
          visible={modalVisible}
          onCancel={() => setModalVisible(false)}
          bodyStyle={{ height: '455px', overflow: 'auto' }}
          width={600}
          footer={footer}
          destroyOnClose={true}
        >
          <Form
            layout="vertical"
            name="formEvents"
            form={form}
            onFinish={onFinish}
            initialValues={initialValues}
            preserve={false}
          >
            <Form.Item label="事件名称" name="name" rules={[{ required: true }]}>
              <Input />
            </Form.Item>
            <Form.Item label="事件说明(选填)" name="description">
              <Input.TextArea maxLength={100} showCount autoSize={{ minRows: 3, maxRows: 3 }} />
            </Form.Item>
            <Tabs defaultActiveKey="trigger">
              <Tabs.TabPane tab="触发设置" key="trigger">
                <Form.Item label="触发字段" name="triggerName" rules={[{ required: true }]}>
                  <Select
                    options={[{ label: '初始化赋值', value: 'initialValue' }, ...options]}
                    style={{ width: 260 }}
                  />
                </Form.Item>
              </Tabs.TabPane>
              <Tabs.TabPane tab="请求设置" key="request" forceRender={true}>
                <Form.Item label="请求类型" name="requestType" rules={[{ required: true }]}>
                  <Radio.Group onChange={radioChange}>
                    <Radio value="get">GET</Radio>
                    <Radio value="post">POST</Radio>
                  </Radio.Group>
                </Form.Item>
                <InsertItem
                  configProps={{
                    label: 'URL',
                    name: 'url',
                    tooltip: 'url中插入的字段值都会强制转为文本',
                    rules: [{ required: true }],
                  }}
                  options={options}
                  type="textarea"
                >
                  <div className={styles.insert}>插入字段</div>
                </InsertItem>
                <Form.Item label="Header/Body">
                  <Button
                    onClick={() => {
                      setHBMVisible(true);
                    }}
                  >
                    点击设置
                  </Button>
                </Form.Item>
                <Form.Item label="返回值格式" name="format">
                  <Radio.Group>
                    <Radio value="JSON">JSON</Radio>
                    <Radio value="XML">XML</Radio>
                  </Radio.Group>
                </Form.Item>
                <Form.Item label="返回值设置">
                  <Button
                    onClick={() => {
                      setResultVisible(true);
                    }}
                  >
                    点击设置
                  </Button>
                </Form.Item>
              </Tabs.TabPane>
            </Tabs>
          </Form>
        </Modal>
        <HBModal
          visible={HBMVisible}
          requestType={requestType}
          headerBody={headerBody}
          options={options}
          onCancel={() => {
            setHBMVisible(false);
          }}
        />
        <ResultModal
          visible={resultVisible}
          options={options}
          resuletData={resultObj.action}
          setResultsObj={setResultObj}
          onCancel={() => {
            setResultVisible(false);
          }}
        />
      </Drawer>
      {/* 调试抽屉弹窗 */}
      <DebuggerDrawer
        visible={debuggingVisible}
        onCancel={() => {
          setDebuggingVisible(false);
        }}
        contentItem={contentItem}
        editItem={editItem}
      />
    </Form.Provider>
  );
};

export default FrontEndEvent;
